package com.vhall.component.service.livecolumn.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.vhall.component.dao.data.AccountForDataMapper;
import com.vhall.component.dao.livecolumn.LiveColumnAttentionMapper;
import com.vhall.component.dao.livecolumn.LiveColumnMapper;
import com.vhall.component.dao.room.RoomMapper;
import com.vhall.component.entity.account.AccountEntity;
import com.vhall.component.entity.account.vo.AccountVO;
import com.vhall.component.entity.audit.dto.AuditRecordListDTO;
import com.vhall.component.entity.audit.dto.CreateAuditRecordDTO;
import com.vhall.component.entity.audit.vo.AuditRecordResponseVO;
import com.vhall.component.entity.data.vo.UserBasicStatisticsRspVO;
import com.vhall.component.entity.data.vo.UserParamVO;
import com.vhall.component.entity.dictionary.enums.ColumnLevelEnum;
import com.vhall.component.entity.dictionary.enums.ColumnOperationalLevelEnum;
import com.vhall.component.entity.dictionary.enums.ColumnWarningEnum;
import com.vhall.component.entity.livecolumn.LiveColumnAttention;
import com.vhall.component.entity.livecolumn.entity.LiveColumnEntity;
import com.vhall.component.entity.livecolumn.entity.LiveColumnUserRelationEntity;
import com.vhall.component.entity.livecolumn.vo.*;
import com.vhall.component.entity.page.vo.PageVO;
import com.vhall.component.entity.room.entity.RoomsEntity;
import com.vhall.component.entity.room.enums.RoomAuditStatusEnum;
import com.vhall.component.entity.subject.enums.StatusEnum;
import com.vhall.component.entity.thirduser.ThirdUserVO;
import com.vhall.component.entity.thirduser.entity.ThirdUserEntity;
import com.vhall.component.entity.thirduser.enums.ThirdUserTypeEnum;
import com.vhall.component.framework.common.exception.BusinessException;
import com.vhall.component.plugin.common.constant.RedisKey;
import com.vhall.component.plugin.common.exception.BizErrorCode;
import com.vhall.component.plugin.common.support.Token;
import com.vhall.component.plugin.common.support.TokenThreadLocal;
import com.vhall.component.plugin.common.utils.BeanCopyUtil;
import com.vhall.component.service.account.AccountService;
import com.vhall.component.service.account.BaseUserPermissionService;
import com.vhall.component.service.audit.AuditRecordService;
import com.vhall.component.service.common.BaseCommonService;
import com.vhall.component.service.livecolumn.LiveColumnService;
import com.vhall.component.service.livecolumn.LiveColumnUserRelationService;
import com.vhall.component.service.thirduser.ThirdUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * LiveColumnServiceImpl-
 *
 * @author xing.wang
 * @date 2023/8/5
 */
@Slf4j
@Service
public class LiveColumnServiceImpl extends BaseUserPermissionService implements LiveColumnService {

    @Value("${guoxin.column.default_pic:''}")
    private String defaultPic;
    @Resource
    private LiveColumnMapper liveColumnMapper;
    @Resource
    private AccountService accountService;
    @Resource
    private RoomMapper roomMapper;
    @Resource
    private LiveColumnAttentionMapper liveColumnAttentionMapper;
    @Resource
    private AuditRecordService auditRecordService;

    @Resource
    private ThirdUserService thirdUserService;

    @Resource
    private LiveColumnUserRelationService liveColumnUserRelationService;
    @Resource
    private AccountForDataMapper accountForDataMapper;

    @Resource
    private BaseCommonService baseCommonService;

    @Resource
    private RedisTemplate redisTemplate;

    /**
     * 置顶上限
     */
    @Value("${guoxin.top.num_limit}")
    private Integer numLimit;

    @Override
    public LiveColumnCreateResponseVO create(LiveColumnCreateRequestVO vo) {
//        判定是否有同名栏目存在
        checkLiveColumnName(vo.getName(), 0);
        List<String> userList = vo.getUserList();
        if (userList.size() >= 6) {
//            关联运营人员不能超过6人
            log.error("关联运营人员不能超过6人,参数信息:{}", vo);
            throw new BusinessException(BizErrorCode.BIZ_LIVE_COLUMN_USER_BIND_FAIL);
        }
        LiveColumnEntity liveColumnEntity = new LiveColumnEntity();
        Token token = TokenThreadLocal.getToken();
        liveColumnEntity.setCreateBy(token.getAccountId());
        liveColumnEntity.setUpdateBy(token.getAccountId());
        liveColumnEntity.setAuditStatus(0);
        LocalDateTime now = LocalDateTime.now();
        liveColumnEntity.setUpdatedAt(now);
        liveColumnEntity.setCreatedAt(now);
        BeanUtil.copyProperties(vo, liveColumnEntity);
        liveColumnEntity.setOrgCode(token.getOrgCode());
        liveColumnEntity.setOrgName(token.getOrgName());


        if (Optional.ofNullable(token.getHeadquartersMarkerFlag()).orElse(false)) {
            liveColumnEntity.setLevel(ColumnLevelEnum.HEADQUARTERS_ORDINARY.getValue());
        } else {
            liveColumnEntity.setLevel(ColumnLevelEnum.BRANCH_NORMAL.getValue());
        }


//        创建栏目
        int insert = liveColumnMapper.insert(liveColumnEntity);
        if (insert >= 1) {
//            创建栏目与运营人员关联

            if (CollUtil.isNotEmpty(userList)) {
                createOrUpdateLiveColumnUserRelation(liveColumnEntity, userList, token);
            }
        }
//        构建返回值
        LiveColumnCreateResponseVO responseVO = new LiveColumnCreateResponseVO();
        BeanUtil.copyProperties(liveColumnEntity, responseVO);
        return responseVO;
    }

    /**
     * 检查直播栏目的名称是否重复
     *
     * @param columnName 栏目名称
     * @param id         当前id
     */
    private void checkLiveColumnName(String columnName, Integer id) {
        LambdaQueryWrapper<LiveColumnEntity> where = Wrappers.lambdaQuery();
        where.eq(LiveColumnEntity::getName, columnName)
                .isNull(LiveColumnEntity::getDeletedAt)
                .ne(LiveColumnEntity::getId, id)
                .last("limit 1");
        LiveColumnEntity liveColumnEntity = liveColumnMapper.selectOne(where);
        if (Objects.nonNull(liveColumnEntity)) {
            //栏目名称存在
            throw new BusinessException(BizErrorCode.BUSINESS_COLUMN_NAME_EXIST);
        }
    }

    /**
     * 创建栏目与运营人员的关联
     *
     * @param liveColumnEntity
     * @param staffUserCode
     * @param token
     */
    private void createOrUpdateLiveColumnUserRelation(LiveColumnEntity liveColumnEntity, List<String> staffUserCode, Token token) {
//        1. 判定当前传递的用户在用户表中存在么
//        2. 存在的直接关联
//        3. 不存在的创建后再进行关联
//        4. 用户信息使用 user_code 进行查询
        List<ThirdUserEntity> thirdUserEntities = thirdUserService.getThirdUserEntitiesBatchSaveOrUpdate(staffUserCode);

        List<String> allUserCode = thirdUserEntities.stream().map(ThirdUserEntity::getUserCode).collect(Collectors.toList());
        if (CollUtil.isEmpty(allUserCode)) {
            throw new BusinessException(20000, "传递的三方用户账号错误", "third_user.err");
        }
        LambdaQueryWrapper<ThirdUserEntity> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.in(ThirdUserEntity::getUserCode, allUserCode).eq(ThirdUserEntity::getUserType, ThirdUserTypeEnum.STAFF.getValue());
//        当前要处理的三方用户信息
        List<ThirdUserEntity> relationUser = thirdUserService.list(queryWrapper);
        if (CollUtil.isNotEmpty(relationUser)) {
            Integer liveColumnEntityId = liveColumnEntity.getId();
            LambdaQueryWrapper<LiveColumnUserRelationEntity> lambdaQuery = Wrappers.lambdaQuery();
            lambdaQuery.eq(LiveColumnUserRelationEntity::getLiveColumnId, liveColumnEntityId);
            List<LiveColumnUserRelationEntity> list = liveColumnUserRelationService.list(lambdaQuery);
            List<LiveColumnUserRelationEntity> liveColumnUserRelationEntities = null;
            if (CollUtil.isEmpty(list)) {
                liveColumnUserRelationEntities = relationUser.stream().map(data -> {
                    LiveColumnUserRelationEntity temp = new LiveColumnUserRelationEntity();
                    temp.setLiveColumnId(liveColumnEntityId);
                    temp.setUserCode(data.getUserCode());
                    temp.setUpdateBy(token.getAccountId());
                    temp.setAccountId(token.getAccountId());
                    return temp;
                }).collect(Collectors.toList());
            } else {
//                当前已经存在的关联信息
                List<String> existsUserCodes = list.stream().map(LiveColumnUserRelationEntity::getUserCode).collect(Collectors.toList());
//                当前需要添加的关联用户信息
                liveColumnUserRelationEntities = relationUser.stream().filter(data -> !existsUserCodes.contains(data.getUserCode())).map(data -> {
                    LiveColumnUserRelationEntity temp = new LiveColumnUserRelationEntity();
                    temp.setLiveColumnId(liveColumnEntityId);
                    temp.setUserCode(data.getUserCode());
                    temp.setUpdateBy(token.getAccountId());
                    temp.setAccountId(token.getAccountId());
                    return temp;
                }).collect(Collectors.toList());
//                需要删除的未关联的数据-已经存在,但是不需要添加
                List<String> removeUserCodes = existsUserCodes.stream().filter(data -> !allUserCode.contains(data)).collect(Collectors.toList());
                if (CollUtil.isNotEmpty(removeUserCodes)) {
                    LambdaQueryWrapper<LiveColumnUserRelationEntity> deleteWhere = Wrappers.lambdaQuery();
                    deleteWhere.in(LiveColumnUserRelationEntity::getUserCode, removeUserCodes)
                            .eq(LiveColumnUserRelationEntity::getLiveColumnId, liveColumnEntityId);
                    liveColumnUserRelationService.remove(deleteWhere);
                }
            }
            liveColumnUserRelationService.saveOrUpdateBatch(liveColumnUserRelationEntities);
        }
    }


    @Override
    public LiveColumnUpdateResponseVO update(LiveColumnUpdateRequestVO vo) {
        Token token = TokenThreadLocal.getToken();
        List<String> userList = vo.getUserList();
        if (userList.size() >= 6) {
//            关联运营人员不能超过6人
            log.error("关联运营人员不能超过6人,参数信息:{}", vo);
            throw new BusinessException(BizErrorCode.BIZ_LIVE_COLUMN_USER_BIND_FAIL);
        }
        LambdaQueryWrapper<LiveColumnEntity> where = Wrappers.lambdaQuery();
        where.eq(LiveColumnEntity::getId, vo.getColumnId())
                .last("limit 1");
        LiveColumnEntity liveColumnEntity = Optional.ofNullable(liveColumnMapper.selectOne(where))
                .orElseThrow(() -> new BusinessException(BizErrorCode.EMPTY_COLUMN));
        checkLiveColumnName(vo.getName(), liveColumnEntity.getId());


        LambdaUpdateWrapper<LiveColumnEntity> wrapper = Wrappers.lambdaUpdate();
        wrapper.set(LiveColumnEntity::getName, vo.getName());
        wrapper.set(LiveColumnEntity::getColumnImageUrl, vo.getColumnImageUrl());
        wrapper.set(LiveColumnEntity::getOrgCode, vo.getOrgCode());
        wrapper.set(LiveColumnEntity::getOrgName, vo.getOrgName());
        wrapper.set(LiveColumnEntity::getDesc, vo.getDesc());
        wrapper.set(LiveColumnEntity::getUpdatedAt, LocalDateTime.now());
        wrapper.set(LiveColumnEntity::getUpdateBy, token.getAccountId());
//        栏目更新后变为待审核
        wrapper.set(LiveColumnEntity::getAuditStatus, RoomAuditStatusEnum.CHECK_PENDING.getAuditStatus());
        wrapper.set(LiveColumnEntity::getTopStatus, StatusEnum.CLOSE.getValue());
        wrapper.set(LiveColumnEntity::getTopStatusAt, null);
        wrapper.eq(LiveColumnEntity::getId, vo.getColumnId());

        int i = liveColumnMapper.update(null, wrapper);
        if (i >= 1) {
//            创建栏目与运营人员关联
            if (CollUtil.isNotEmpty(userList)) {
                createOrUpdateLiveColumnUserRelation(liveColumnEntity, userList, token);
            }
        }
        LiveColumnUpdateResponseVO responseVO = new LiveColumnUpdateResponseVO();
        BeanUtil.copyProperties(liveColumnEntity, responseVO);
        return responseVO;
    }

    @Override
    public Boolean delete(LiveColumnDeleteRequestVO vo) {
        LambdaQueryWrapper<LiveColumnEntity> where = Wrappers.lambdaQuery();
        where.eq(LiveColumnEntity::getId, vo.getColumnId())
                .last("limit 1");
        LiveColumnEntity liveColumnEntity = Optional.ofNullable(liveColumnMapper.selectOne(where))
                .orElseThrow(() -> new BusinessException(BizErrorCode.EMPTY_COLUMN));

        checkLiveColumnDelete(vo);

        liveColumnEntity.setDeletedAt(LocalDateTime.now());
        int i = liveColumnMapper.updateById(liveColumnEntity);
        return i >= 1;
    }

    /**
     * 检查栏目是否可以删除
     *
     * @param vo
     */
    private void checkLiveColumnDelete(LiveColumnDeleteRequestVO vo) {
        LambdaQueryWrapper<RoomsEntity> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(RoomsEntity::getColumnId, vo.getColumnId());
        List<RoomsEntity> roomsEntities = roomMapper.selectList(queryWrapper);
        if (CollUtil.isNotEmpty(roomsEntities)) {
            BusinessException businessException = new BusinessException(BizErrorCode.BUSINESS_COLUMN_EXIST_ROOM_LK);
            String ilIds = roomsEntities.stream().map(data -> data.getIlId().toString()).collect(Collectors.joining(","));
            businessException.setMsg("已被" + ilIds + "关联，无法删除，请取消关联后重试！");
            throw businessException;
        }
    }

    @Override
    public LiveColumnInfoResponseVO getLiveColumn(LiveColumnInfoRequestVO vo) {
        LiveColumnInfoResponseVO responseVO = getLiveColumnInfoResponseVO(vo);
        Integer updateBy = responseVO.getUpdateBy();
        AccountEntity updateUser = accountService.getById(updateBy);
        if (Objects.nonNull(updateUser)) {
            responseVO.setUpdateName(updateUser.getNickname());
            responseVO.setUpdateOrgCode(updateUser.getOrgCode());
            responseVO.setUpdateOrgName(updateUser.getOrgName());
        }
        List<ThirdUserVO> userList = liveColumnUserRelationService.listRelationThirdUser(vo.getColumnId());
        responseVO.setUserList(userList);
        return responseVO;
    }

    @NotNull
    private LiveColumnInfoResponseVO getLiveColumnInfoResponseVO(LiveColumnInfoRequestVO vo) {
        LambdaQueryWrapper<LiveColumnEntity> where = Wrappers.lambdaQuery();
        where.eq(LiveColumnEntity::getId, vo.getColumnId())
                .isNull(LiveColumnEntity::getDeletedAt)
                .last("limit 1");
        LiveColumnEntity liveColumnEntity = Optional.ofNullable(liveColumnMapper.selectOne(where))
                .orElseThrow(() -> new BusinessException(BizErrorCode.EMPTY_COLUMN));
        LiveColumnInfoResponseVO responseVO = new LiveColumnInfoResponseVO();
        BeanUtil.copyProperties(liveColumnEntity, responseVO);
        baseCommonService.convertUrl(responseVO, "columnImageUrl");
        return responseVO;
    }

    @Override
    public LiveColumnInfoResponseVO info(LiveColumnInfoRequestVO vo) {
        if (vo.getColumnId() == null || vo.getColumnId() == 0) {
            LiveColumnInfoResponseVO liveColumnInfoResponseVO = new LiveColumnInfoResponseVO();
            liveColumnInfoResponseVO.setColumnImageUrl(defaultPic);
            liveColumnInfoResponseVO.setName("国信直播间");
            return liveColumnInfoResponseVO;
        }
        Token token = TokenThreadLocal.getToken();
        LiveColumnInfoResponseVO liveColumnInfoResponseVO = getLiveColumnInfoResponseVO(vo);
        // 订阅数
        LambdaQueryWrapper<LiveColumnAttention> liveColumnAttentionLambdaQueryWrapper = Wrappers.lambdaQuery();
        liveColumnAttentionLambdaQueryWrapper.eq(LiveColumnAttention::getColumnId, liveColumnInfoResponseVO.getId());
        liveColumnAttentionLambdaQueryWrapper.isNull(LiveColumnAttention::getDeletedAt);
        Integer fansCount = liveColumnAttentionMapper.selectCount(liveColumnAttentionLambdaQueryWrapper);
        liveColumnInfoResponseVO.setFansCount((fansCount == null ? 0 : fansCount) * 11);
        //房间总数
        LambdaQueryWrapper<RoomsEntity> roomsEntityLambdaQueryWrapper = Wrappers.lambdaQuery();
        roomsEntityLambdaQueryWrapper.eq(RoomsEntity::getColumnId, vo.getColumnId());
        roomsEntityLambdaQueryWrapper.eq(RoomsEntity::getAuditStatus, 1);
        roomsEntityLambdaQueryWrapper.eq(RoomsEntity::getLiveRormal, 1);
        List<RoomsEntity> roomsEntityList = roomMapper.selectList(roomsEntityLambdaQueryWrapper);
        liveColumnInfoResponseVO.setRoomCount(roomsEntityList.size());
        //观看数
        Integer watchCount = 0;
        List<Integer> ilIdList = roomsEntityList.stream().map(RoomsEntity::getIlId).collect(Collectors.toList());
        Integer pvSum = roomsEntityList.stream().mapToInt(data -> Optional.ofNullable(data.getTotalNumberOfViews()).orElse(0)).sum();
        UserParamVO userParamVO = new UserParamVO();
        userParamVO.setIlIdList(ilIdList);
        UserBasicStatisticsRspVO ubsrv = accountForDataMapper.getBasicStatisticsInfo(userParamVO);
        UserBasicStatisticsRspVO ubsrvVod = accountForDataMapper.getVodBasicStatisticsInfo(userParamVO);
        if (ubsrv != null) {
            watchCount += ubsrv.getPvCount();
        }
        if (ubsrvVod != null) {
            watchCount += ubsrvVod.getPvCount();
        }
        if (Objects.nonNull(pvSum)) {
            watchCount += pvSum;
        }
        liveColumnInfoResponseVO.setConnectCount(watchCount);
        if (token != null) {
            liveColumnAttentionLambdaQueryWrapper = Wrappers.lambdaQuery();
            liveColumnAttentionLambdaQueryWrapper.eq(LiveColumnAttention::getColumnId, liveColumnInfoResponseVO.getId());
            liveColumnAttentionLambdaQueryWrapper.eq(LiveColumnAttention::getUserCode, token.getThirdPartyUserId());
            liveColumnAttentionLambdaQueryWrapper.isNull(LiveColumnAttention::getDeletedAt);
            Integer count = liveColumnAttentionMapper.selectCount(liveColumnAttentionLambdaQueryWrapper);
            liveColumnInfoResponseVO.setIsSubscribe(count > 0 ? 1 : 0);
        }
//        if (vo.getIlId() != null){
//            List<Integer> idList = new ArrayList<>();
//            idList.add(vo.getIlId());
//            UserParamVO paramVO = new UserParamVO();
//            paramVO.setIlIdList(idList);
//            UserBasicStatisticsRspVO live = accountForDataMapper.getBasicStatisticsInfo(paramVO);
//            UserBasicStatisticsRspVO rec = accountForDataMapper.getVodBasicStatisticsInfo(paramVO);
//            Long countSum = 0L;
//            if (live != null) {
//                countSum += live.getPvCount();
//            }
//            if (rec != null) {
//                countSum += rec.getPvCount();
//            }
//
//            QueryWrapper<RoomStatsExpansion> queryWrapper = Wrappers.query();
//            queryWrapper.eq("il_id", vo.getIlId());
//            Integer selectCount = roomStatsExpansionMapper.selectCount(queryWrapper);
//            if (selectCount > 0){
//                queryWrapper.select("SUM(expansion_number) as total");
//                List<Map<String, Object>> mapList = roomStatsExpansionMapper.selectMaps(queryWrapper);
//                Map<String, Object> objectMap = mapList.get(0);
//                Object total = objectMap.get("total");
//                if (total == null){
//                    total = "0";
//                }
//                countSum += Long.parseLong(String.valueOf(total));
//            }
//
//            String key = "virtual:connect:count:" + vo.getColumnId() + ":" + vo.getIlId();
//            Long count = countSum;
//            int randomNumber = getRandomNumber();
//            if (Boolean.TRUE.equals(redisTemplate.hasKey(key))){
//                 count = redisTemplate.opsForValue().increment(key, randomNumber);
//            }else {
//                count = redisTemplate.opsForValue().increment(key, count + randomNumber);
//            }
//            RoomsEntity roomsEntity = roomMapper.selectById(vo.getIlId());
//            liveColumnInfoResponseVO.setVirtualConnectCount(count);
//            redisTemplate.expire(key, 1, TimeUnit.DAYS);
//
//            RoomStatsExpansion roomStatsExpansion = new RoomStatsExpansion();
//            roomStatsExpansion.setIlID(vo.getIlId());
//            roomStatsExpansion.setExpansionNumber(randomNumber);
//            roomStatsExpansion.setCreateTime(new Date());
//            roomStatsExpansionMapper.insert(roomStatsExpansion);
//
//
//            JSONObject body = new JSONObject();
//            body.put("type", "column_virtual_connect_count");
//            body.put("room_id", roomsEntity.getRoomId());
//            body.put("column_id", vo.getColumnId());
//            body.put("virtual_connect_count", count);
//            paasService.sendMessage(roomsEntity.getChannelId(), body.toJSONString());
//
//        }

        return liveColumnInfoResponseVO;
    }

    private int getRandomNumber() {
        int min = 5;
        int max = 10;

        Random random = new Random();

        return random.nextInt(max - min + 1) + min;
    }

    @Override
    public PageVO<LiveColumnBaseResponseVO> pageList(LiveColumnPageListRequestVO reqVO) {


        Page<LiveColumnEntity> page = new Page<>(reqVO.getPage(), reqVO.getPageSize());
        LambdaQueryWrapper<LiveColumnEntity> where = Wrappers.lambdaQuery();
        where.isNull(LiveColumnEntity::getDeletedAt);
        where.eq(StrUtil.isNotBlank(getUserPermission()), LiveColumnEntity::getOrgCode, getUserPermission());
        where.eq(reqVO.getAuditStatus() != null, LiveColumnEntity::getAuditStatus, reqVO.getAuditStatus());
        where.like(StringUtils.isNotBlank(reqVO.getKeyword()), LiveColumnEntity::getName, reqVO.getKeyword());
//        where.last("ORDER BY  top_status_at desc, FIELD(`level`,1,3,2,4) , recent_month_views_count desc ");
        where.orderByDesc(LiveColumnEntity::getUpdatedAt);
        page = liveColumnMapper.selectPage(page, where);
        List<LiveColumnBaseResponseVO> vos = new ArrayList<>();
        if (page != null && CollectionUtil.isNotEmpty(page.getRecords())) {

            List<LiveColumnEntity> records = page.getRecords();
            vos = BeanCopyUtil.batchCopy(records, LiveColumnBaseResponseVO::new);
            for (LiveColumnBaseResponseVO vo : vos) {
                baseCommonService.convertUrl(vo, "columnImageUrl");
            }

        }

        return new PageVO<>(reqVO.getPage(), reqVO.getPageSize(), page != null ? Integer.parseInt(String.valueOf(page.getTotal())) : 0, vos);


    }

    @Override
    public PageVO<LiveColumnAuditListResponseVO> auditPageList(LiveColumnPageListRequestVO reqVO) {
        Page<LiveColumnEntity> page = new Page<>(reqVO.getPage(), reqVO.getPageSize());
        LambdaQueryWrapper<LiveColumnEntity> wrapper = Wrappers.lambdaQuery();
        String keyword = reqVO.getKeyword();
        String orgCode = reqVO.getOrgCode();
        Integer auditStatus = reqVO.getAuditStatus();
        String userPermission = getUserPermission();
//        数据权限
        wrapper.eq(StringUtils.isNotBlank(userPermission), LiveColumnEntity::getOrgCode, userPermission);
        wrapper.like(StrUtil.isNotBlank(keyword), LiveColumnEntity::getName, keyword)
                .isNull(LiveColumnEntity::getDeletedAt)
                .ne(LiveColumnEntity::getAuditStatus, RoomAuditStatusEnum.SUBMIT_FOR_APPROVAL.getAuditStatus())
                .eq(Objects.nonNull(auditStatus), LiveColumnEntity::getAuditStatus, auditStatus)
                .eq(StrUtil.isNotBlank(orgCode), LiveColumnEntity::getOrgCode, orgCode)
                .orderByDesc(LiveColumnEntity::getId)
        ;
        page = liveColumnMapper.selectPage(page, wrapper);
        List<LiveColumnEntity> records = page.getRecords();
        List<LiveColumnAuditListResponseVO> commentListRspVos = buildLiveColumnAuditListInfo(records);
        return new PageVO<>(reqVO.getPage(), reqVO.getPageSize(), (int) page.getTotal(), commentListRspVos);
    }

    @Override
    public Boolean subscribe(Integer columnId) {
        Token token = TokenThreadLocal.getToken();
        Integer accountId = token.getAccountId();
        String userCode = token.getThirdPartyUserId();
        LambdaQueryWrapper<LiveColumnAttention> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(LiveColumnAttention::getColumnId, columnId);
        queryWrapper.eq(LiveColumnAttention::getAccountId, accountId);
        queryWrapper.isNull(LiveColumnAttention::getDeletedAt);
        queryWrapper.last(" limit 1");
        LiveColumnAttention liveColumnAttention = liveColumnAttentionMapper.selectOne(queryWrapper);
        if (liveColumnAttention == null) {
            liveColumnAttention = new LiveColumnAttention();
            liveColumnAttention.setColumnId(columnId);
            liveColumnAttention.setAccountId(accountId);
            liveColumnAttention.setUserCode(userCode);
            liveColumnAttention.setCreatedAt(new Date());
            liveColumnAttention.setUpdatedAt(new Date());
            liveColumnAttention.setCreateBy(accountId);
            liveColumnAttention.setUpdateBy(accountId);
            if (liveColumnAttentionMapper.insert(liveColumnAttention) > 0) {
                String key = RedisKey.CACHE_COLUMN_SUB + columnId + ":" + accountId;
                redisTemplate.opsForValue().set(key, 1, 1, TimeUnit.HOURS);
                String setKey = RedisKey.CACHE_COLUMN_SUB_SET + columnId;
                redisTemplate.opsForSet().add(setKey, accountId);
                redisTemplate.expire(setKey, 1, TimeUnit.HOURS);

            }
            return true;
        } else {
            throw new BusinessException(60000, "已订阅", "");
        }
    }

    @Override
    public Boolean unsubscribe(Integer columnId) {
        Token token = TokenThreadLocal.getToken();
        Integer accountId = token.getAccountId();
        LiveColumnAttention liveColumnAttention = new LiveColumnAttention();
        LambdaQueryWrapper<LiveColumnAttention> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(LiveColumnAttention::getColumnId, columnId);
        queryWrapper.eq(LiveColumnAttention::getAccountId, accountId);
        liveColumnAttention.setDeletedAt(new Date());
        liveColumnAttention.setUpdatedAt(new Date());
        liveColumnAttention.setUpdateBy(accountId);
        if (liveColumnAttentionMapper.update(liveColumnAttention, queryWrapper) > 0) {
            String key = RedisKey.CACHE_COLUMN_SUB + columnId + ":" + accountId;
            redisTemplate.opsForValue().set(key, 0, 1, TimeUnit.HOURS);
            String setKey = RedisKey.CACHE_COLUMN_SUB_SET + columnId;
            redisTemplate.opsForSet().remove(setKey, accountId);
            redisTemplate.expire(setKey, 1, TimeUnit.HOURS);
        }

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean auditLiveColumn(AuditLiveColumnRequestVO vo) {
        LambdaQueryWrapper<LiveColumnEntity> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(LiveColumnEntity::getId, vo.getLiveColumnId()).last("limit 1");
        LiveColumnEntity liveColumnEntity = Optional.ofNullable(liveColumnMapper.selectOne(queryWrapper)).orElseThrow(() -> new BusinessException(BizErrorCode.EMPTY_COLUMN));
        liveColumnEntity.setAuditStatus(vo.getAuditStatus());
        liveColumnEntity.setAuditNote(vo.getAuditNote());
        liveColumnEntity.setAuditAt(LocalDateTime.now());
        int update = liveColumnMapper.updateById(liveColumnEntity);
        if (update >= 1) {
            CreateAuditRecordDTO dto = new CreateAuditRecordDTO();
            dto.setAuditTable("live_column");
            dto.setAuditComments(vo.getAuditNote());
            dto.setAuditStatus(vo.getAuditStatus());
            dto.setAuditTableRecordId(vo.getLiveColumnId().toString());
            auditRecordService.createAuditRecord(dto);
        }
        return true;
    }

    @Override
    public Boolean isSubscribe(Integer columnId, Integer accountId) {
        String key = RedisKey.CACHE_COLUMN_SUB + columnId + ":" + accountId;
        String setKey = RedisKey.CACHE_COLUMN_SUB_SET + columnId;
        if (redisTemplate.hasKey(key)) {
            Object value = redisTemplate.opsForValue().get(key);
            Integer sub = Integer.parseInt(String.valueOf(value));
            if (sub == 1) {
                redisTemplate.opsForSet().add(setKey, accountId);
                redisTemplate.expire(setKey, 1, TimeUnit.HOURS);
            }
            return sub == 1;
        } else {
            LambdaQueryWrapper<LiveColumnAttention> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.eq(LiveColumnAttention::getColumnId, columnId);
            queryWrapper.eq(LiveColumnAttention::getAccountId, accountId);
            queryWrapper.isNull(LiveColumnAttention::getDeletedAt);
            queryWrapper.last(" limit 1");
            LiveColumnAttention liveColumnAttention = liveColumnAttentionMapper.selectOne(queryWrapper);
            if (Objects.isNull(liveColumnAttention)) {
                redisTemplate.opsForValue().set(key, 0, 1, TimeUnit.HOURS);
                return false;
            } else {
                redisTemplate.opsForValue().set(key, 1, 1, TimeUnit.HOURS);
                redisTemplate.opsForSet().add(setKey, accountId);
                redisTemplate.expire(setKey, 1, TimeUnit.HOURS);
                return true;
            }
        }
    }

    @Override
    public List<AuditRecordResponseVO> liveColumnAuditRecordList(LiveColumnAuditRecordListRequestVO vo) {
        AuditRecordListDTO dto = new AuditRecordListDTO();
        dto.setAuditTable("live_column");
        dto.setAuditTableRecordId(vo.getLiveColumnId().toString());
        return auditRecordService.getAuditRecordList(dto);
    }

    @Override
    public PageVO<LiveColumnOperListRsponseVO> columnOperationsList(LiveColumnOperListRequestVO vo) {

        Page<LiveColumnEntity> page = new Page<>(vo.getPage(), vo.getPageSize());
        LambdaQueryWrapper<LiveColumnEntity> where = Wrappers.lambdaQuery();
        where.isNull(LiveColumnEntity::getDeletedAt);
        where.eq(LiveColumnEntity::getAuditStatus, RoomAuditStatusEnum.APPROVED.getAuditStatus());
        where.like(StringUtils.isNotBlank(vo.getName()), LiveColumnEntity::getName, vo.getName());
        where.eq(vo.getLevel() != null, LiveColumnEntity::getLevel, vo.getLevel());
        where.eq(StringUtils.isNotBlank(vo.getOrgCode()), LiveColumnEntity::getOrgCode, vo.getOrgCode());
        where.eq(StrUtil.isNotBlank(getUserPermission()), LiveColumnEntity::getOrgCode, getUserPermission());
        where.last("ORDER BY top_status_at desc,FIELD(`level`,1,3,2,4) , recent_month_views_count desc,id desc ");
        page = liveColumnMapper.selectPage(page, where);
        List<LiveColumnOperListRsponseVO> vos = new ArrayList<>();
        if (page != null && CollectionUtil.isNotEmpty(page.getRecords())) {

            List<LiveColumnEntity> records = page.getRecords();
            // 获取创建人
            List<AccountVO> entities = accountService.listByIds(records.stream().map(LiveColumnEntity::getCreateBy).collect(Collectors.toList()));
            Map<Integer, AccountVO> accountVOMap = new HashMap<>();
            if (CollectionUtil.isNotEmpty(entities)) {
                accountVOMap = entities.stream().collect(Collectors.toMap(AccountVO::getAccountId, e -> e));
            }
            vos = BeanCopyUtil.batchCopy(records, LiveColumnOperListRsponseVO::new);
            for (LiveColumnOperListRsponseVO listRsponseVO : vos) {
                listRsponseVO.setOperationalLevelName(ColumnOperationalLevelEnum.getName(listRsponseVO.getOperationalLevel()));
                listRsponseVO.setCreateName(!accountVOMap.isEmpty() ? accountVOMap.get(listRsponseVO.getCreateBy()).getUsername() : "");
                listRsponseVO.setLevelName(ColumnLevelEnum.getName(listRsponseVO.getLevel()));
                baseCommonService.convertUrl(listRsponseVO, "columnImageUrl");
            }
        }

        return new PageVO<>(vo.getPage(), vo.getPageSize(), page != null ? Integer.parseInt(String.valueOf(page.getTotal())) : 0, vos);

    }

    @Override
    public Boolean adjustingOperLevels(LiveAdjustingOperLevelsVO vo) {
        LambdaUpdateWrapper<LiveColumnEntity> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(LiveColumnEntity::getId, vo.getColumnId())
                .set(LiveColumnEntity::getLevel, vo.getLevel());

        if (vo.getLevel().equals(ColumnLevelEnum.HEADQUARTERS_BOUTIQUE.getValue())
                || vo.getLevel().equals(ColumnLevelEnum.BRANCH_BOUTIQUE.getValue())) {
            wrapper.set(LiveColumnEntity::getLevelTime, LocalDateTime.now());
        }

        wrapper.set(LiveColumnEntity::getOperationalLevel, ColumnWarningEnum.NORMAL.getValue());
        liveColumnMapper.update(null, wrapper);
        return true;
    }

    @Override
    public Boolean topColumn(LiveTopOperVO vo) {
        LambdaUpdateWrapper<LiveColumnEntity> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(LiveColumnEntity::getId, vo.getColumnId());
        wrapper.set(LiveColumnEntity::getTopStatus, vo.getType());
        LocalDateTime topStatusAt;
        if (vo.getType().equals(StatusEnum.OPEN.getValue())) {
            topStatusAt = LocalDateTime.now();
        } else {
            topStatusAt = null;
        }
        wrapper.set(LiveColumnEntity::getTopStatusAt, topStatusAt);
        liveColumnMapper.update(null, wrapper);
        return true;
    }

    @Override
    public Boolean topColumnNum() {
        LambdaQueryWrapper<LiveColumnEntity> where = Wrappers.lambdaQuery();
        where.eq(LiveColumnEntity::getTopStatus, StatusEnum.OPEN.getValue());
        where.eq(LiveColumnEntity::getAuditStatus, RoomAuditStatusEnum.APPROVED.getAuditStatus());
        where.isNull(LiveColumnEntity::getDeletedAt);
        Integer integer = liveColumnMapper.selectCount(where);
        return integer < numLimit;
    }

    @Override
    public Boolean isSub(Integer columnId) {
        Token token = TokenThreadLocal.getToken();
        Integer accountId = token.getAccountId();
        return isSubscribe(columnId,accountId);
    }

    @Override
    public List<LiveColumnBaseResponseVO> roleAllLiveColumnList() {
        LambdaQueryWrapper<LiveColumnEntity> where = Wrappers.lambdaQuery();
        where.isNull(LiveColumnEntity::getDeletedAt).eq(LiveColumnEntity::getAuditStatus, RoomAuditStatusEnum.APPROVED.getAuditStatus());
        where.eq(StrUtil.isNotBlank(getUserPermission()), LiveColumnEntity::getOrgCode, getUserPermission());
        List<LiveColumnEntity> liveColumnEntities = liveColumnMapper.selectList(where);
        List<LiveColumnBaseResponseVO> result;
        result = liveColumnEntities.stream().map(data -> {
            LiveColumnBaseResponseVO temp = new LiveColumnBaseResponseVO();
            BeanUtil.copyProperties(data, temp);
            baseCommonService.convertUrl(temp, "columnImageUrl");
            return temp;
        }).collect(Collectors.toList());
        return result;
    }

    /**
     * 构建直播栏目审核列表
     *
     * @param records
     * @return
     */
    private List<LiveColumnAuditListResponseVO> buildLiveColumnAuditListInfo(List<LiveColumnEntity> records) {
        List<LiveColumnAuditListResponseVO> commentListRspVos = new ArrayList<>();

        if (CollUtil.isNotEmpty(records)) {
            List<Integer> createIds = records.stream().map(LiveColumnEntity::getCreateBy).collect(Collectors.toList());
            List<AccountEntity> accountEntityList = accountService.getAccountIntoList(createIds);
            Map<Integer, List<AccountEntity>> accountMap = accountEntityList.stream().collect(Collectors.groupingBy(AccountEntity::getAccountId));
            if (CollUtil.isNotEmpty(accountEntityList)) {
                commentListRspVos = records.stream().map(liveColumn -> {
                    LiveColumnAuditListResponseVO data = new LiveColumnAuditListResponseVO();
                    BeanUtil.copyProperties(liveColumn, data);
                    Integer createBy = liveColumn.getCreateBy();
                    data.setCreateBy(createBy);
                    List<AccountEntity> accountEntityList1 = accountMap.get(createBy);
                    if (Objects.nonNull(accountEntityList1)) {
                        AccountEntity accountEntity = accountEntityList1.get(0);
                        data.setCreateName(accountEntity.getNickname());
                    }
                    baseCommonService.convertUrl(data, "columnImageUrl");
                    return data;
                }).collect(Collectors.toList());
            }
        }
        return commentListRspVos;
    }
}
